﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GcmpDatabase.h"
#include "GbmpTypeDefs.h"
#include "GbmpGuid.h"
#include "GcmpApiDeclaration.h"
#include "GbmpQuickCast.h"
#include <string>
#include <unordered_set>
#include <unordered_map>

namespace gcmp
{
    class ClassId;
    class NdbClassSchema;

    typedef std::unordered_map<Int64, std::unordered_map<UInt32, ClassId>> ElementSchemaMapForUnserializing;

    class GCMP_DATABASE_EXPORT NdbClassSchemaLibrary
    {
        DEFINE_CAST_BASE(gcmp::NdbClassSchemaLibrary)
    public:
        NdbClassSchemaLibrary();

        virtual UInt32 GetClassSchemaCount() const = 0;

        virtual UInt32 GetMajorVersion() const = 0;

        // 应该返回刚刚加入的ClassSchema的指针
        virtual NdbClassSchema * AddClassSchema(OwnerPtr<NdbClassSchema> opClassSchema) = 0;

        virtual bool GetClassIdByIndex(UInt32 index, ClassId & classId) const = 0;

        virtual const NdbClassSchema* GetSchemaByClassId(const ClassId & classId) const = 0;

        virtual bool BuildClassHierarchy() = 0;

        virtual bool IncreaseBuildClassHierarchy(NdbClassSchema * pBuildingClassSchema) = 0;

        virtual std::wstring GetName() const = 0;

    public:
        virtual ~NdbClassSchemaLibrary();

        bool HasClassSchemasOfAssembly(const Guid & assembly) const;

        bool IsClassHierarchyBuilt() const { return m_isClassHierarchyBuilt; }

        const std::set<UInt32>* GetClassSchemasOfAssembly(const Guid& guid) const;

        const Guid* GetAssemblyGuidByName(const std::wstring& name) const;

    protected:
        bool m_isClassHierarchyBuilt;

        // 按Assembly分类ClassSchema
        std::unordered_map < Guid, std::set<UInt32>, GuidHasher, GuidEqual > m_classSchemasByAssembly;
        // 存储AssemblyName与Guid 关系
        std::unordered_map < std::wstring, Guid> m_AssemblyNameToGuid;

        // 读取对象时使用(TODO: 在该类和子类中使用如下两个变量会导致线程安全问题，禁止使用，如下两个变量将和上面4个废弃接口在到期日一并删除)
        Int64 m_unserializingElementId = -1;
        ElementSchemaMapForUnserializing m_elementSchemaMapForUnserializing;
    private:
        friend class NdbClassSchemaLibraryUtils;
    };
}
